package org.zecontech.extraplus.datagen.levelgen;

import net.minecraft.core.HolderGetter;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BiomeDefaultFeatures;
import net.minecraft.data.worldgen.BootstrapContext;
import net.minecraft.resources.ResourceKey;
import net.minecraft.sounds.Music;
import net.minecraft.sounds.Musics;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.Mth;
import net.minecraft.world.level.biome.AmbientMoodSettings;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeGenerationSettings;
import net.minecraft.world.level.biome.BiomeSpecialEffects;
import net.minecraft.world.level.biome.MobSpawnSettings;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import org.zecontech.extraplus.util.Helpers;

import javax.annotation.Nullable;

/**
 * 生物群系提供者
 */
public class ModBiomeProvider {

    public static final ResourceKey<Biome> WILLOW_FOREST =
            register("willow_foreset");

    public static void addBiomes(BootstrapContext<Biome> context) {
        HolderGetter<PlacedFeature> holderGetter = context.lookup(Registries.PLACED_FEATURE);
        HolderGetter<ConfiguredWorldCarver<?>> worldCarvers = context.lookup(Registries.CONFIGURED_CARVER);
        context.register(WILLOW_FOREST, willowForest(holderGetter, worldCarvers));
    }

    /**
     * 柳树森林
     * @param placedFeatures 生成特征
     * @param worldCarvers 世界 carved
     * @return 柳树森林
     */
    public static Biome willowForest(HolderGetter<PlacedFeature> placedFeatures, HolderGetter<ConfiguredWorldCarver<?>> worldCarvers) {
        BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(placedFeatures, worldCarvers);
        globalOverworldGeneration(builder);
        Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_FOREST);
        BiomeDefaultFeatures.addForestFlowers(builder);
        BiomeDefaultFeatures.addDefaultOres(builder);
        BiomeDefaultFeatures.addDefaultSoftDisks(builder);
        BiomeDefaultFeatures.addBushes(builder);
        BiomeDefaultFeatures.addDefaultFlowers(builder);
        BiomeDefaultFeatures.addForestGrass(builder);
        BiomeDefaultFeatures.addDefaultMushrooms(builder);
        BiomeDefaultFeatures.addDefaultExtraVegetation(builder, true);
        builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, ModPlacedFeatureProvider.WILLOW);
        builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, ModPlacedFeatureProvider.FALLEN_WILLOW_TREE);
        MobSpawnSettings.Builder mobspawnsettings$Builder = new MobSpawnSettings.Builder();
        BiomeDefaultFeatures.farmAnimals(mobspawnsettings$Builder);
        BiomeDefaultFeatures.commonSpawns(mobspawnsettings$Builder);
        return biome(true, 0.7F, 0.8F, mobspawnsettings$Builder, builder, music);
    }

    /**
     * 全局生成设置
     * @param generationSettings 生成设置
     */
    private static void globalOverworldGeneration(BiomeGenerationSettings.Builder generationSettings) {
        BiomeDefaultFeatures.addDefaultCarversAndLakes(generationSettings);
        BiomeDefaultFeatures.addDefaultCrystalFormations(generationSettings);
        BiomeDefaultFeatures.addDefaultMonsterRoom(generationSettings);
        BiomeDefaultFeatures.addDefaultUndergroundVariety(generationSettings);
        BiomeDefaultFeatures.addDefaultSprings(generationSettings);
        BiomeDefaultFeatures.addSurfaceFreezing(generationSettings);
    }

    /**
     * 生物群系
     * @param hasPercipitation 降水
     * @param temperature 温度
     * @param downfall 雨量
     * @param mobSpawnSettings 生物生成设置
     * @param generationSettings 生成设置
     * @param backgroundMusic 背景音乐
     * @return 生物群系
     */
    private static Biome biome(boolean hasPercipitation, float temperature, float downfall, MobSpawnSettings.Builder mobSpawnSettings, BiomeGenerationSettings.Builder generationSettings, @Nullable Music backgroundMusic) {
        return biome(hasPercipitation, temperature, downfall, 4159204, 329011, (Integer)null, (Integer)null, (Integer)null, mobSpawnSettings, generationSettings, backgroundMusic);
    }

    /**
     * 计算天空颜色
     * @param temperature 温度
     * @return 天空颜色
     */
    protected static int calculateSkyColor(float temperature) {
        float $$1 = temperature / 3.0F;
        $$1 = Mth.clamp($$1, -1.0F, 1.0F);
        return Mth.hsvToRgb(0.62222224F - $$1 * 0.05F, 0.5F + $$1 * 0.1F, 1.0F);
    }

    /**
     * 生物群系
     * @param hasPrecipitation 降水
     * @param temperature 温度
     * @param downfall 雨量
     * @param waterColor 水颜色
     * @param waterFogColor 水雾颜色
     * @param grassColorOverride 草颜色
     * @param foliageColorOverride  foliage颜色
     * @param dryFoliageColorOverride 干草颜色
     * @param mobSpawnSettings 生物生成设置
     * @param generationSettings 生成设置
     * @param backgroundMusic 背景音乐
     * @return 生物群系
     */
    private static Biome biome(boolean hasPrecipitation, float temperature, float downfall, int waterColor, int waterFogColor, @Nullable Integer grassColorOverride, @Nullable Integer foliageColorOverride, @Nullable Integer dryFoliageColorOverride, MobSpawnSettings.Builder mobSpawnSettings, BiomeGenerationSettings.Builder generationSettings, @Nullable Music backgroundMusic) {
        BiomeSpecialEffects.Builder biomespecialeffects$builder = (new BiomeSpecialEffects.Builder()).waterColor(waterColor).waterFogColor(waterFogColor).fogColor(12638463).skyColor(calculateSkyColor(temperature)).ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS).backgroundMusic(backgroundMusic);
        if (grassColorOverride != null) {
            biomespecialeffects$builder.grassColorOverride(grassColorOverride);
        }

        if (foliageColorOverride != null) {
            biomespecialeffects$builder.foliageColorOverride(foliageColorOverride);
        }

        if (dryFoliageColorOverride != null) {
            biomespecialeffects$builder.dryFoliageColorOverride(dryFoliageColorOverride);
        }

        return (new Biome.BiomeBuilder()).hasPrecipitation(hasPrecipitation).temperature(temperature).downfall(downfall).specialEffects(biomespecialeffects$builder.build()).mobSpawnSettings(mobSpawnSettings.build()).generationSettings(generationSettings.build()).build();
    }

    /**
     * 注册生物群系
     * @param key 资源键
     * @return 生物群系
     */
    private static ResourceKey<Biome> register(String key) {
        return ResourceKey.create(Registries.BIOME, Helpers.identifier(key));
    }
}
